<?php


namespace Soen\Http\Server;


use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Soen\Container\Error\Error;
use Soen\Di\DiProvider;
use Soen\Http\Message\Factory\StreamFactory;
use Soen\Http\Message\HttpRequest;
use Soen\Http\Message\Response;
use Soen\Http\Message\ServerRequest;
use Soen\Http\Server\Middleware\MiddlewareDispatcher;
use Soen\Router\Exception\NotFoundException;
use Soen\Router\Provider;
use Soen\Router\RouteCurrent;
use Soen\Router\Router;
use Soen\Router\RouterProvider;
use Soen\Session\Session;

class RequestHandler implements RequestHandlerInterface
{
    /**
     * @var Response
     */
	public $response;
	public $request;
	/**
	 * @var RouterProvider
	 */
	public $routerProvider;
	/**
	 * @var RouteCurrent
	 */
	public $routeCurrent;
    /**
     * @var Error
     */
	public $error;

	/**
	 * RequestHandler constructor.
	 * @param ResponseInterface $response
	 * @param $routerProvider
	 */
	public function __construct(ResponseInterface $response, $routerProvider)
	{
		$this->response = $response;
		$this->routerProvider = $routerProvider;
//		$this->error =
	}

	/**
	 * @param ServerRequestInterface $request
	 * @return ResponseInterface
	 * @throws Exception\TypeException
	 */
	public function handle(ServerRequestInterface $request):Response
	{
        if ($request->getSwooleRequest()->server['path_info'] == '/favicon.ico' || $request->getSwooleRequest()->server['request_uri'] == '/favicon.ico') {
            return $this->response;
        }
        try {
            $this->routeCurrent = $this->routerProvider->setRouteCurrent($request);
            if ($getParams = $this->routeCurrent->getParams()) {
                $request->withQueryParams($getParams);
            }
        } catch (NotFoundException $error) {
            // 404 处理
            AbnormalResuest::route404($this->response);
            return $this->response;
        }
        /**
         * 初始化session
         * @var Session $session
         */
//        $session = context()->getComponent('session');
//        $session->start($request, $this->response);
        \App::getContext()->setContextData('request', $request);
        \App::getContext()->setContextData('response', $this->response);
        /* 中间件执行 */
        (new MiddlewareDispatcher($this->routeCurrent->getMiddlewares(), $request, $this->response))->dispatch();
		list($className, $action) = $this->routeCurrent->getClassAction();
        $reflectionMethod = new \ReflectionMethod($className, $action);
        $httpRequest = new HttpRequest($request);
        $executeData = $reflectionMethod->invokeArgs(new $className, [$httpRequest]);
//		$executeData = call_user_func_array($this->routeCurrent->getClassAction(true), $this->routeCurrent->getParams());
        if(!$executeData){
            return $this->response;
        }
        if(\App::$app->configArray['response']['contentType'] === 'json'){
            $executeDataJson = json_encode($executeData, JSON_UNESCAPED_UNICODE);
            $streamBody = (new StreamFactory())->createStream($executeDataJson);
            $this->response->withBody($streamBody);
            $this->response->withContentType('application/json', 'utf-8');
        }
		return $this->response;
	}

}